<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<link rel="stylesheet" href="../style/journal.css" type="text/css" />
<style type="text/css"><!--
.googleadsense {
	margin: 2px;
	padding: 0px;
//--></style><script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-65008-1";
urchinTracker();
</script><title>modperl 的 PerlTransHandler 应用</title>
</head>
<body>
<a href="index.html">Journal</a>(2005) | <a href="../blog/"><b>Blog</b></a>(2006) | <a href="http://www.fayland.org/cgi-bin/random_link.pl">RandomLink</a> | <a href="AboutFayland.html">WhoAmI</a> | <a href="LiveBookmark.html">LiveBookmark</a> | <a href="http://www.fayland.org/">HomePage</a>
<p><&lt;Previous: <a href="modperl_http_cycle.html">modperl 服务器的运行阶段和句柄</a>&nbsp;&nbsp;>>Next: <a href="C3_method_resolution_orde.html">C3 method resolution order</a></p>
<h1>modperl 的 PerlTransHandler 应用</h1>
<div class='content'>
<p>Category: <a href='mod_perl.html'>mod_perl</a> &nbsp; Keywords: <b>modperl PerlTransHandler</b></p>这次讲 <a href="http://perl.apache.org">modperl</a> 的PerlTransHandler，主要的作用是 url rewrite<h3>PerlTransHandler</h3>前面 <a href='modperl_http_cycle.html'>modperl 服务器的运行阶段和句柄</a> 中讲过 PerlTransHandler 主要用于处理 URI<br />如果你用过 mod_rewrite 的话，发现这个 handler 比 mod_rewrite 更实用。<p />假设我们为了对搜索引擎友好，将动态的 URL 地址类如<br /><pre>http://www.fayland.org/cgi-bin/topic.cgi?id=44<br />http://www.fayland.org/cgi-bin/topic.cgi?id=44&type=print</pre>分别转为对搜索引擎更友好的静态地址如<br /><pre>http://www.fayland.org/topic/44<br />http://www.fayland.org/topic/print/44</pre>我没用 mod_rewrite 转过，但是试验过 PerlTransHandler:<br /><pre>package MyApache2::RewriteTopic;<p />use strict;<br />use warnings;<p />use Apache2::RequestRec ();<p />use Apache2::Const -compile => qw(DECLINED);<p />sub handler {<br /> &nbsp; &nbsp;my $r = shift;<p /> &nbsp; &nbsp;# for http://www.fayland.org/topic/44<br /> &nbsp; &nbsp;if ($r->uri =~ m|^/topic/(\d+)/?|) {<br /> &nbsp; &nbsp; &nbsp; &nbsp;$r->uri("/cgi-bin/topic.cgi");<br /> &nbsp; &nbsp; &nbsp; &nbsp;$r->args("id=$1");<br /> &nbsp; &nbsp;}<br /> &nbsp; &nbsp;# for http://www.fayland.org/topic/print/44<br /> &nbsp; &nbsp;if ($r->uri =~ m|^/topic/([a-z]+)/(\d+)/?|) {<br /> &nbsp; &nbsp; &nbsp; &nbsp;$r->uri("/cgi-bin/topic.cgi");<br /> &nbsp; &nbsp; &nbsp; &nbsp;$r->args("id=$2&amp;type=$1");<br /> &nbsp; &nbsp;}<p /> &nbsp; &nbsp;return Apache2::Const::DECLINED;<br />}<p />1;<br /></pre>在 perl.conf 或 httpd.conf 增加：<br /><pre>PerlTransHandler +MyApache2::RewriteTopic</pre>或者是<br /><pre>PerlModule MyApache2::RewriteTopic<br />PerlTransHandler MyApache2::RewriteTopic</pre>两者是等同的。<p /><ul>其间值得提提的有一下几点：<br /><li>$r->uri 设定转向的 URI</li><li>$r->args 设定参数/parameters 这些参数可以用 CGI 的 param 来获取</li><li>Apache2::Const::DECLINED<br />我在前面的那文章里讲过 PerlTransHandler 的类型是 RUN_FIRST，所以当我们返回 DECLINED 时，接下来的 hook 也能被执行。<p />比如我们另外定义了一个 MyApache2::RewriteView 这个模块唯一不同的就是把 topic 改为 view, 且在 perl.conf 里增加 PerlTransHandler +MyApache2::RewriteTopic +MyApache2::RewriteView<p />修改完后当我们碰到类如 http://www.fayland.org/view/77 时，虽然 MyApache2::RewriteTopic 不满足，但是由于它返回的是 Apache2::Const::DECLINED, 所以会接下来继续下面的 MyApache2::RewriteView。<br />而如果 RewriteTopic 返回的是 Apache2::Const::OK, 那接下来的 MyApache2::RewriteView 就不会再继续了。<br /></ul>另外注意将 $r->uri("/cgi-bin/topic.cgi"); $r->args("id=$1"); 放到 if 里面，否则将 PerlTransHandler +MyApache2::RewriteTopic 放到某个 Location 里。<br />要不弄成全局，就将所有的 URI 都转向 topic.cgi 了。:)<p /></div>
<p><&lt;Previous: <a href="modperl_http_cycle.html">modperl 服务器的运行阶段和句柄</a>&nbsp;&nbsp;>>Next: <a href="C3_method_resolution_orde.html">C3 method resolution order</a></p>
<p><strong>Options:</strong> <a href='http://del.icio.us/post?title=modperl%20%E7%9A%84%20PerlTransHandler%20%E5%BA%94%E7%94%A8&url=http://www.fayland.org/journal/modperl_PerlTransHandler.html'>+Del.icio.us</a></p>
<strong>Related items</strong>
<ul><li><a href='modperl_helloworld.html'>modperl Apache2::HelloWorld</a> < <span class='digit'>2005-11-16 23:24:07</span> ></li><li><a href='modperl_http_cycle.html'>modperl 服务器的运行阶段和句柄</a> < <span class='digit'>2005-11-22 15:33:08</span> ></li><li><a href='modperl_PerlAuthenHandler.html'>modperl 的用户验证</a> < <span class='digit'>2005-11-26 00:08:37</span> ></li><li><a href='modperl_Filter_part1.html'>modperl Filter Part1</a> < <span class='digit'>2005-12-18 14:47:29</span> ></li></ul>
Created on <span class="digit">2005-11-23 22:24:02</span>, Last modified on <span class="digit">2005-11-25 11:42:52</span><br />
Copyright 2004-2005 All Rights Reserved. Powered by <a href="Eplanet.html">Eplanet</a> && <a href='http://catalyst.perl.org'>Catalyst</a> 5.62.
</body>
</html>